DashBoard 首页:Turnstile 验证组件封装与实例方法暴露
概述
管理端 Dashboard 首页集成了 Cloudflare Turnstile 人机验证组件。本节重点讲解如何封装 Turnstile 组件并通过 defineExpose 暴露实例方法,供父组件获取验证 Token、重置验证状态等操作。
Turnstile 组件封装
基本结构
<!-- components/Turnstile.vue -->
<template>
<div ref="turnstileRef" class="turnstile-container"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
const props = defineProps<{
siteKey: string
}>()
const emit = defineEmits<{
(e: 'verify', token: string): void
(e: 'expire'): void
(e: 'error', message: string): void
}>()
const turnstileRef = ref<HTMLDivElement>()
const widgetId = ref<string | null>(null)
// 渲染 Turnstile 组件
function render() {
if (!turnstileRef.value || !window.turnstile) return
widgetId.value = window.turnstile.render(turnstileRef.value, {
sitekey: props.siteKey,
callback: (token: string) => emit('verify', token),
'error-callback': (message: string) => emit('error', message),
'expired-callback': () => emit('expire'),
})
}
onMounted(() => {
render()
})
onBeforeUnmount(() => {
destroy()
})
</script>
vue
暴露实例方法
通过 defineExpose 向父组件暴露操作方法:
// 重置验证
function reset() {
if (widgetId.value) {
window.turnstile.reset(widgetId.value)
}
}
// 获取验证响应
function getResponse(): string | undefined {
if (widgetId.value) {
return window.turnstile.getResponse(widgetId.value)
}
}
// 获取 DOM 实例
function getInstance() {
return turnstileRef.value
}
// 销毁组件
function destroy() {
if (widgetId.value) {
window.turnstile.remove(widgetId.value)
widgetId.value = null
}
}
defineExpose({
getInstance,
reset,
getResponse,
destroy,
})
typescript
父组件使用
<template>
<div>
<Turnstile ref="turnstileRef" :site-key="SITE_KEY" @verify="onVerify" />
<el-button @click="handleTest">Test</el-button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Turnstile from '@/components/Turnstile.vue'
const turnstileRef = ref<InstanceType<typeof Turnstile>>()
function onVerify(token: string) {
console.log('验证成功,Token:', token)
}
function handleTest() {
// 打印暴露的方法
console.log(turnstileRef.value)
// 获取验证响应
const response = turnstileRef.value?.getResponse()
console.log('验证响应:', response)
// 重置验证
// turnstileRef.value?.reset()
}
</script>
vue
defineExpose 方法清单
| 方法 | 说明 | 返回值 |
|---|---|---|
getInstance() | 获取 Turnstile DOM 实例 | HTMLDivElement | undefined |
reset() | 重置验证状态,重新触发校验 | void |
getResponse() | 获取验证通过的 Token | string | undefined |
destroy() | 销毁 Turnstile 实例,释放资源 | void |
实践要点
widgetId在render成功后赋值,用于后续的reset、getResponse和remove操作- 组件卸载时务必调用
destroy()清理 Turnstile 实例,避免内存泄漏 getResponse()返回的 Token 有时效性,过期后会触发expire回调- 可在 Dashboard 首页的测试按钮中验证所有暴露方法是否正常工作
↑